Coding conventions used in UZI

UZI is coded in decent, recent and standard C++.  
Because UZI is supposed to run on any platform, a drastic selection has been made on the additional libraries/dependencies required.
Similarly, UZI code base is kept simple to avoid current -memory-hungry- application behaviour.

From my previous experiencies, there is no truely cross-platform STL library. Similarly, Boost library was forbidden for it's bad behaviour on compilation time, and STL library dependencies.

A. Decent C++

This means that obfuscated C++ (like obscure operator overloading, mixed private & public inheritance, ...) are not/must not be used.
In case operator overloading is not obvious, but required for code simplification, it's clearly stated in the documentation.

At the same time, almost all C++ specific features are used (like placement new, pure virtual methods, constructor based initialization, namespaces, template etc...), so it's required to know this C++ rules in order to be able to understand the current code, and write new code. Almost all modern object-oriented programming langage use these features, so this shouldn't be to different to Java, D and C# developers.

Exceptions should be avoided as much as possible as exception handling takes time, and isn't implemented correctly on every platform.

The code follows strong coding conventions which are:
  1. Every namespace, typedef, define, class, member, method is documented following DOxygen syntax (see below for code example).  This allows documentation to always be in-sync with code.
  2. Documentation is grouped by semantically-equivalent types (members are grouped by accessibility, method are grouped by interface, type definition are grouped too, etc...). This allows fast code review
  3. Method and functions must document their parameters names, return types, and usage description.
  4. Code should follow basic Object-oriented programming concept (such as encapsulation, interfaces)
  5. Member names are capitalized, except for the first word (see below for code example). There is no prefix letter, nor suffix.
  6. Member names are expected to be short, but still made of entire words (theNumberOfRows is not good, while rowCount is)
  7. Methods follow member rules, expect for one-word method name which are capitalized (like setAnswerCode() and Suicide())
  8. Methods that shouldn't modify their object must be declared const
  9. Similarly, when an object is shared in multithreaded environment, it should be declared volatile, method that accept being called by multiple thread simultaneously must be declared volatile.
  10. Declaration should be in header files with .hpp extension, and definition should be in source file with .cpp extension.
  11. Files should be grouped semantically in the same folder with the common semantic name (like GUI, Component, Parser, Strings, and so on)
  12. Method definition shouldn't be too long. If a method definition is too long, it should be split in multiple sub method. 
  13. When dealing with an external object that won't change in the whole scope, a reference is preffered instead of pointers. There is less code to type, and it's easier to read.
  14. When returning the address of an object, a pointer is used only if it's required to return 0 as an error code.
  15. Preprocessor macro use should be avoided as much as possible
  16. Following those rules make the code easy to read and understand, and ensure developers won't waste their time rewriting an existing code.

B. Recent C++

The C++ features used include templates, placement new and exceptions. This appeared in ANSI standardization of 1998.
UZI uses these features, hence can't be compiled on previous compiler. However, some new features are not used (like RTTI, partial template specialization, any type, and others).

Even if the next definition is not acceptable, let's say that  Visual C++ 6.0 compiler should be able to compile UZI in any current or future version.
This allows Embedded Visual C++ 4.0 to be used too.

C. Standard C++

All platform specific code is moved to very specific files, so when compiling on a different platform, the minimum porting work is required on those files only.
This means that the code shouldn't be encumbered by #ifdef _WIN32 and other oddities.
Because of poor Microsoft based compiler, some warning have to be turned off with #pragma specific directive, and they should be done in a common file.
Please avoid compiler specific extension (like variable parameters macro of gcc) as it breaks on standard C++ compiler.

D. Documentation

UZI is using Doxygen as the documentation engine.
This means that you can use any Doxygen command inside your comment to see them appearing in the documentation.
By convention, we only use /** Doxygen's start code for general comments and //!< for inline enum member documentation, and Doxygen's command starts by @.
Everything must be documented (from private members to public static functions, if any).
Functions and methods must have both their parameters and return type documented (unless it's obvious).
If a function or a class is usage is non-trivial, it's recommended to document its usage in @code / @endcode blocs with // comments.

E. Members grouping

Even with the best documentation around, there are still reasons to dig in the code.
In order to make this experience the less painful as possible, we usually group functionally equivalent member in the same section, with a // comment before the section access policy (public, private or protected).
It's common to find a // Member section, a // ABaseClass Interface section, a // Helpers section, a // Construction and destruction section and so on, in the current classes.

 Example source code and its documentation, and some comment

Header : Elements.hpp in include/HTMLParser folder Comment
/** The base element class
    The positions are set like specified in this schematic :
    @verbatim
    <element some_attribute>
     |                     |__ endPosition
     |__ startPosition

    ... [ Content ] ...

    </element              >
      |                    |___ finalPosition
      |__ endTagPosition
    @endverbatim

    If the element doesn't have an end tag, either it is because:
    - No end tag is allowed (like BR), then both its endTagPosition and finalPosition are set to endPosition
    - The end tag is optional (like LI), then both its endTagPosition and finalPosition are set to the found end position
      (either on startPosition of a new element of the same type) or parent's endTagPosition
       
*/
class Element
{
    // Type definitions   
public:
    /** Inject the Element ID enumeration in our class */
    typedef HTML::GenericElement::ElementID   ElementID;
    /** The validation rules type definition */
    typedef const HTML::GenericElement * const ValidationRules;

    // Members
private:
    /** The element type */
    const ElementID                           elementType;
    /** The element start position in stream */
    uint32                                    startPosition;
    /** The element end position in stream */
    uint32                                    endPosition;

    // Interface
public:   
    /** This method returns the tag name as a char array */
    const tchar * tagName() const volatile { return elementType == HTML::GenericElement::Unknown ? "" : allowedElements[(int)elementType - 1].name; }          
    /** Get the rule for this element or 0 if not identifiable element */
    inline ValidationRules getValidationRules() const { return elementType == HTML::GenericElement::Unknown ? 0 : &allowedElements[(int)elementType - 1]; }

    // Accessors
public:
    /** Set the end position
        @param position The new end position
        @sa Element for details where the position are */
    inline void setEndPosition(uint32 position)     { endPosition = position; }
    /** Set the start position
        @param position The new start position
        @sa Element for details where the position are */
    inline void setStartPosition(uint32 position)   { startPosition = position; }

    /** Get the start position */
    inline uint32 getStartPosition()    const { return startPosition; }
    /** Get the end position */
    inline uint32 getEndPosition()      const { return endPosition; }

    /** Get the element type */
    inline const ElementID & getElementType() const   { return elementType; }


    // Construction
public:
    /** Default constructor */
    Element(const ElementID type = HTML::GenericElement::Unknown, uint32 startPos = 0, uint32 endPos = 0) : elementType(type), startPosition(startPos), endPosition(endPos) {}
    /** Copy constructor */
    Element(const Element & element) : elementType(element.elementType), startPosition(element.startPosition), endPosition(element.endPosition) {}
};
All documentation start by /** and finish by */
For enumeration, it's required to document every member with //!<

Documentation follow Doxygen format

















Members are grouped by semantical functions

Every member is documented




Members themselves are private


If they don't change, member are declared const
Every member word is capitalized, expect the first





Method are also grouped by semantical functions

When a method can be called by multiple thread, it must be volatile
Similarly when a method doesn't modify the object, it must be const


Methods that use a parameter must document it
Return should be documented, unless obvious















Construction and destruction should be in their own section too.





(C) An X-Ryl669 project 2007

This document describes Unlimited Zooming Interface source code. UZI stands for Unlimited Zooming Interface, and source code license is